/**
 * creation: 7-okt-2007
 */
package org.jfonia.pitch;

/**
 * class which supports base-40 pitches/intervals (Hewlett).
 * Note that middle-C (C4, lower C on G-clef) is chosen to be 0 in this implementation, 
 * whereas it is 103 in the original article.
 * 
 * @see http://www.ccarh.org/publications/reprints/base40/
 * @author Wijnand
 *
 */
public class Base40
{
	/**
	 * base40-value of middle C (lower C on G-clef). Note: in the original Hewlett-version, this was 103.
	 */
	public static final int middleC = 0; 
	
	public static final int UNISON = 0;
	public static final int OCTAVE = 40;
	
	public static final int PERRECT_UNISON = 0;
	
	public static final int MINOR_SECOND = 5;
	public static final int MAJOR_SECOND = 6;
	public static final int AUGMENTED_SECOND = 7;
	
	public static final int MINOR_THIRD = 11;
	public static final int MAJOR_THIRD = 12;
	public static final int AUGMENTED_THIRD = 13;
	
	public static final int DIMINISHED_FOURTH = 16;
	public static final int PERFECT_FOURTH = 17;
	public static final int AUGMENTED_FOURTH = 18;	// also: raised fourth or tritone
	
	public static final int DIMINISHED_FIFTH = 22;
	public static final int PERFECT_FIFTH = 23;
	public static final int AUGMENTED_FIFTH = 24;	// also: raised
	
	public static final int MINOR_SIXTH = 28;
	public static final int MAJOR_SIXTH = 29;
	public static final int AUGMENTED_SIXTH = 30;
	
	public static final int DIMINISHED_SEVENTH = 33;
	public static final int MINOR_SEVENTH = 34;
	public static final int MAJOR_SEVENTH = 35;
	
	public static final int PERFECT_OCTAVE = 40;
	
	public static final int C = 0;
	public static final int D = 6;
	public static final int E = 12;
	public static final int F = 17;
	public static final int G = 23;
	public static final int A = 29;
	public static final int B = 35;
	
	// note: adding large numbers to make integer division correct for negative rank/base40

	public static int toBase40(MusicalInterval ival)
	{
		return (ival.getRank()*40 + 7005) / 7 - 1000 + ival.getAccidental();
	}
	
	public static MusicalInterval toMusicalInterval(int base40)
	{
		int rank = (7*base40+40015)/40 - 1000; 
		int mod = base40 - (40*rank+7005)/7 + 1000;
		return new MusicalInterval(rank, mod);
	}

}
